﻿namespace GoodAdmin.System;

/// <inheritdoc cref="IRelationService"/>
public class RelationService : DbRepository<SysRelation>, IRelationService, ITransient
{
    private readonly IRedisCacheManager _redisCacheManager;

    public RelationService(IRedisCacheManager redisCacheManager)
    {
        _redisCacheManager = redisCacheManager;
    }
    /// <inheritdoc/>
    public async Task AddRelation(string Category, long objectId, List<long> TargetIds, List<string> ExtraJson = null)
    {
        List<SysRelation> relationList = new List<SysRelation>();
        for (int i = 0; i < TargetIds.Count; i++)
        {
            relationList.Add(new SysRelation
            {
                Category = Category,
                ObjectId = objectId,
                TargetId = TargetIds[i],
                ExtraJson = ExtraJson?[i]
            });
        }
        if (relationList.Count == 0) return;
        if (await InsertRangeAsync(relationList))
            RemoveCache(Category);
    }

    public async Task AddRelation(string Category, long ObjectId, long TargetId, string ExtraJson = null)
    {
        var relation = new SysRelation
        {
            Category = Category,
            ObjectId = ObjectId,
            TargetId = TargetId,
            ExtraJson = ExtraJson
        };
        if (await InsertAsync(relation))
        {
            RemoveCache(Category);
        }
    }

    /// <inheritdoc/>
    public async Task AddRelationByTargetId(string Category, long TargetId, List<long> ObjectIds, List<string> ExtraJson = null)
    {
        List<SysRelation> relationList = new List<SysRelation>();
        for (int i = 0; i < ObjectIds.Count; i++)
        {
            relationList.Add(new SysRelation
            {
                Category = Category,
                ObjectId = ObjectIds[i],
                TargetId = TargetId,
                ExtraJson = ExtraJson?[i]
            });
        }
        if (relationList.Count == 0) return;
        if (await InsertRangeAsync(relationList))
            RemoveCache(Category);
    }

    /// <inheritdoc/>
    public async Task DeleteRelationByCategoryAndObjectId(string Category, long ObjectId)
    {
        await DeleteAsync(r => r.Category == Category && r.ObjectId == ObjectId);
        RemoveCache(Category);
    }

    /// <inheritdoc/>
    public async Task DeleteRelationByCategoryAndObjectId(string Category, List<long> ObjectIds)
    {
        await DeleteAsync(r => r.Category == Category && ObjectIds.Contains(r.ObjectId));
        RemoveCache(Category);
    }

    /// <inheritdoc/>
    public async Task DeleteRelationByCategoryAndTargetId(string Category, long TargetId)
    {
        await DeleteAsync(r => r.Category == Category && r.TargetId == TargetId);
        RemoveCache(Category);
    }

    /// <inheritdoc/>
    public async Task DeleteRelationByCategoryAndTargetId(string Category, List<long> TargetIds)
    {
        await DeleteAsync(r => r.Category == Category && TargetIds.Contains(r.TargetId));
        RemoveCache(Category);
    }

    /// <inheritdoc/>
    public async Task<List<SysRelation>> GetRelationListByObjectId(string Category, long ObjectId)
    {
        var relationList = await GetRelationListByCategory(Category);
        return relationList.Where(r => r.ObjectId == ObjectId).ToList();
    }

    /// <inheritdoc/>
    public async Task<List<SysRelation>> GetRelationListByTargetId(string Category, long TargetId)
    {
        var relationList = await GetRelationListByCategory(Category);
        return relationList.Where(r => r.TargetId == TargetId).ToList();
    }

    /// <inheritdoc/>
    public async Task<List<SysRelation>> GetRelationListByTargetId(string Category, List<long> TargetIds)
    {
        var relationList = await GetRelationListByCategory(Category);
        return relationList.Where(r => TargetIds.Contains(r.TargetId)).ToList();
    }

    /// <inheritdoc/>
    public async Task<List<SysRelation>> GetRelationListByObjectIdList(string Category, List<long> ObjectIds)
    {
        var relationList = await GetRelationListByCategory(Category);
        return relationList.Where(r => ObjectIds.Contains(r.ObjectId)).ToList();
    }


    private async Task<List<SysRelation>> GetRelationListByCategory(string Category)
    {
        var key = CacheConst.SysRelation + Category;
        var relation = _redisCacheManager.Get<List<SysRelation>>(key);
        if (relation == null)
        {
            relation = await GetListAsync(r => r.Category == Category);
            _redisCacheManager.Set(key, relation);
        }
        return relation;
    }

    private void RemoveCache(string Category)
    {
        var key = CacheConst.SysRelation + Category;
        _redisCacheManager.Remove(key);
    }
}